package registry

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"sync"
)

const ServerPort = ":4000"
const ServicesUrl = "http://localhost" + ServerPort + "/services"

type registry struct {
	registration []Registration
	mutex        *sync.Mutex
}

func (r *registry) add(registration Registration) error {
	r.mutex.Lock()
	defer r.mutex.Unlock()
	r.registration = append(r.registration, registration)
	return nil
}
func (r *registry) remove(url string) error {
	for i, reg := range r.registration {
		if reg.ServiceUrl == url {
			r.mutex.Lock()
			defer r.mutex.Unlock()
			r.registration = append(r.registration[:i], r.registration[i+1:]...)
			return nil
		}
	}
	return fmt.Errorf("service not found")
}

var reg = registry{
	registration: make([]Registration, 0),
	mutex:        new(sync.Mutex),
}

type RegistryService struct{}

func (rs *RegistryService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Println("RegistryService ServerHttp")
	switch r.Method {
	case http.MethodPost:
		dec := json.NewDecoder(r.Body)
		var r Registration
		if err := dec.Decode(&r); err != nil {
			log.Println(err)
			w.WriteHeader(http.StatusBadRequest)
			return
		}
		log.Printf("Add ServerHttp: %+v, %+v\n", r.ServiceName, r.ServiceUrl)
		if err := reg.add(r); err != nil {
			log.Println(err)
			w.WriteHeader(http.StatusBadRequest)
			return
		}
		w.WriteHeader(http.StatusOK)
		return
	case http.MethodDelete:
		paload, err := io.ReadAll(r.Body)
		if err != nil {
			log.Println(err)
			w.WriteHeader(http.StatusBadRequest)
			return
		}
		url := string(paload)
		if err := reg.remove(url); err != nil {
			log.Println(err)
			w.WriteHeader(http.StatusBadRequest)
			return
		}
		log.Printf("Remove ServerHttp: %+v\n", url)
		w.WriteHeader(http.StatusOK)
		return
	default:
		w.WriteHeader(http.StatusMethodNotAllowed)
		return
	}
}
